//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
/// @file
///
///
/// 
/// @author Davide Pasca
/// 
//==================================================================

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rendm5d_displist.h"

//===============================================================================
RendM5D::DispList::DispList( M5D::DispList *dlistp, RendDevice *rdevicep ) :
	_dlistp(dlistp),
	_rdevicep(rdevicep),
	_last_buff_idx(0)
{
	// $$$ DAVIDE - ummm - PASSERT( _rdevicep->IsRendering() == false );

	_dlistp = dlistp;
	_dlistp->_userdatap = (void *)this;

	for (int i=0; i < 2; ++i)
	{
		_vbuffsp[i] = NULL;
		_ibuffsp[i] = NULL;
	}

	updateBuffers();
}

//===============================================================================
RendM5D::DispList::~DispList()
{
	// $$$ DAVIDE - ummm - PASSERT( _rdevicep->IsRendering() == false );

	for (int i=0; i < 2; ++i)
	{
		delete _vbuffsp[i];
		delete _ibuffsp[i];
	}
}

//===============================================================================
void RendM5D::DispList::updateBuffers()
{
	if NOT( _dlistp.needs_update() )
		return;

	// $$$ DAVIDE - ummm - PASSERT( _rdevicep->IsRendering() == false );

	_last_buff_idx ^= 1;

	int	i = _last_buff_idx;

	// create/upload the vertex buffer
	if NOT( _vbuffsp[i] )
		_vbuffsp[i] = new RendVertexBuffer( _rdevicep, _dlistp->GetMaxVerts(), _dlistp->GetVertStride() );
	else
		_vbuffsp[i]->ReallocBuffer( _dlistp->GetMaxVerts(), _dlistp->GetVertStride() );

	_vbuffsp[i]->UploadData( _dlistp->_vert_def.GetVertPtr( 0, M5D::VType::POS ), 0, _dlistp->GetMaxUsedVerts() );

	// create/upload the index buffer
	if ( _dlistp->IsIndexType() )
	{
		if NOT( _ibuffsp[i] )
			_ibuffsp[i] = new RendIndexBuffer( _rdevicep, _dlistp->GetMaxIndices() );
		else
			_ibuffsp[i]->ReallocBuffer( _dlistp->GetMaxIndices() );

		_ibuffsp[i]->UploadData( _dlistp->GetFirstIndexPtr(), 0, _dlistp->GetMaxUsedIndices() );
	}
}

//===============================================================================
void RendM5D::DispList::SelectBuffers()
{
	int	i = _last_buff_idx;

	updateBuffers();
	_rdevicep->SelectVertexBuffer( _vbuffsp[i] );

#ifdef TARGET_D3D
	if ( _ibuffsp[i] )
	{
		D3DDevice	*d3ddevp = _rdevicep->GetD3DDevice();

		if ( _ibuffsp[i]->GetD3DIBuff() )
			d3ddevp->SetIndices( _ibuffsp[i]->GetD3DIBuff() );
	}
#endif
}
